import unittest
import copy
import NetworkBuilder

class NetworkBuilderTest(unittest.TestCase):
    
    NETWORK_FILE = "campinas.net.xml"
    NODE_NAME = "bernardinoxglicerio"
    EXPECTED_NODES = ["startBernardino",      "bernardinoxglicerio", "endBernardino",
                      "startBJaguara",        "conceicaoxbrjaguara", "generalxbrjaguara",
                      "endBJaguara",          "startCamposSales",    "camposSales",
                      "campossalesxglicerio", "endCamposSales",      "startConceicao",
                      "conceicaoxglicerio",   "endConceicao",        "startGeneral",
                      "generalxglicerio",     "endGeneral",          "startGlicerio",
                      "endGlicerio"]
    EXPECTED_LINKS = { "startBernardino" : ["generalxglicerio", "endBernardino"],
                       "startGlicerio"   : ["generalxglicerio", "endBernardino"]}
    EXPECTED_PHASES = ["GGrr","yyrr", "rrGG", "rryy"]
    
    def setUp(self):
        self.net = NetworkBuilder.buildNetwork(self.NETWORK_FILE)
    
    def test_node(self):
        node = self.net.getNodeByName(self.NODE_NAME)
        
        self.assertIsNotNone(node, "Cannot find node %s on network" %(self.NODE_NAME))
       
    def test_edge(self): 
        edgeBernardinoSeg1Name = "bernardinoSeg1"
        edgeBernardinoSeg1 = self.net.getEdgeByName(edgeBernardinoSeg1Name)
        
        self.assertIsNotNone(edgeBernardinoSeg1, "Cannot find edge %s on network" %(edgeBernardinoSeg1Name))
        
    def test_links(self):
        node = self.net.getNodeByName(self.NODE_NAME)
        
        linksCount = node.getLinkCount()
        self.assertEquals(4, linksCount, "Cannot find the expected number of links")
        self.assertLinks(4, self.EXPECTED_LINKS, node)
        
    def test_phases(self):
        node = self.net.getNodeByName(self.NODE_NAME)
        
        """We expect 4 phases for this test since the node bernardinoxglicerio has 2 incoming nodes and 2 outcoming"""
        phasesCount = node.getPhaseCount()
        self.assertEquals(4, phasesCount, "Cannot find the expected number of phases") 
        
        myExpectedPhase = copy.deepcopy(self.EXPECTED_PHASES)
        
        for phaseIndex in range(4):
            phase = node.getPhase(phaseIndex)
            self.assertLinks(4, self.EXPECTED_LINKS, phase)
            
            """Test phase values"""
            for linkIndex in range(4) :
                linkStatus = phase.getStatus(linkIndex)
                expectedStatus = myExpectedPhase[phaseIndex][linkIndex]
                self.assertEquals(expectedStatus,
                                  linkStatus, 
                                  "Link with a wrong status in %d a phase (expected: %s, found: %s)" % (phaseIndex, expectedStatus, linkStatus));

    def assertLinks(self, amount, expectedLinks, linkContainer):
        myExpectedLinks = copy.deepcopy(expectedLinks)
        for i in range(amount) :
            link = linkContainer.getLink(i)    
            fromNode = link.getFrom()
            toNode   = link.getTo()
            
            self.assertIsNotNone(fromNode, "Link has no from node")
        
            fromNodeId = fromNode.getId()
            self.assertIn(fromNodeId, myExpectedLinks, "Node %s not expected in a link" % (fromNodeId))
            
            toNodeId = toNode.getId()
            targetNodeList = myExpectedLinks[fromNodeId]
            self.assertIn(toNodeId, targetNodeList, "Node %s not expected in a link")
            targetNodeList.remove(toNodeId)
            
            if len(targetNodeList) == 0:
                del myExpectedLinks[fromNodeId]
                
        self.assertEquals(0, len(myExpectedLinks), "Cannot find on network structure the following links %s" % (expectedLinks))
     